/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.editors.support;

import nu.xom.Document;
import nu.xom.Serializer;
import org.apache.commons.codec.Charsets;
import org.apache.commons.lang3.StringUtils;
import org.zkoss.io.Files;
import org.zkoss.util.resource.Locators;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.StringTokenizer;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
public abstract class CodeFormatter {

	private static Invocable invocable;

	// private static Object options;

	static {
		ScriptEngineManager engineManager = new ScriptEngineManager();
		ScriptEngine engine;

		if (System.getProperty("java.version").startsWith("1.8")) {
			engine = engineManager.getEngineByName("nashorn");
		} else {
			engine = engineManager.getEngineByName("JavaScript");
		}
		try {
			String basePath = "web/js/";
			InputStream is;

			is = Locators.getDefault().getResourceAsStream(
					basePath + "beautify.js");
			engine.eval(new String(Files.readAll(is), Charsets.UTF_8));
			is.close();

			is = Locators.getDefault().getResourceAsStream(
					basePath + "beautify-css.js");
			engine.eval(new String(Files.readAll(is), Charsets.UTF_8));
			is.close();

			is = Locators.getDefault().getResourceAsStream(
					basePath + "beautify-html.js");
			engine.eval(new String(Files.readAll(is), Charsets.UTF_8));
			is.close();

			invocable = (Invocable) engine;
			// Object json = engine.eval("JSON");
			// options = invocable.invokeMethod(json, "parse",
			// "{\"indent_size\": 2}");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static String formatXML(Document xml) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		Serializer serializer = new MultiplexSerializer(out);
		try {
			serializer.setIndent(2);
			serializer.write(xml);
			String str = out.toString("UTF-8");
			return str;
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} finally {
			try {
				out.close();
			} catch (Exception e) {
			}
		}
	}

	public static String formatCSS(String css) {
		if (StringUtils.isBlank(css)) {
			return "";
		}
		try {
			css = (String) invocable.invokeFunction("css_beautify", "<style>"
					+ css + "</style>");
			StringBuilder sb = new StringBuilder();
			StringTokenizer tokenizer = new StringTokenizer(css, "\n", true);
			while (tokenizer.hasMoreElements()) {
				String line = tokenizer.nextToken();
				if (line.contains("<style>")) {
					line = line.replaceFirst("<style>", "");
					line = line.trim();
				} else if (line.contains("</style>")) {
					line = line.replaceFirst("</style>", "");
				}
				sb.append(line);
			}
			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	public static String formatJS(String js) {
		try {
			return (String) invocable.invokeFunction("js_beautify", js);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	public static String formatHTML(String html) {
		try {
			return (String) invocable.invokeFunction("html_beautify", html);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

}
